package com.pboc.service;

import com.pboc.base.BaseException;
import com.pboc.base.ClassUtil;
import com.pboc.base.PageModel;
import com.pboc.dao.SysWageDao;
import com.pboc.entity.SysWage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class SysWageService {
    @Autowired
    private SysWageDao sysWageDao;

    public void getList(PageModel<SysWage> pageModel) {
        try {
            pageModel.setRows(sysWageDao.pageQuery(pageModel));
            pageModel.setTotal(sysWageDao.getListCount(pageModel.getQueryObj()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void updateWage(SysWage sysWage) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        initWage(sysWage);
        sysWageDao.update(sysWage);
    }

    public void del(Integer id) {
        sysWageDao.delete(id);
    }

    /**
     * 一键生成上月工资
     */
    public void initWageForMonth() {
        Map map = new HashMap();
        //获取上上个月工资集合
        SysWage wage = new SysWage();
        String preMonth = getMonthStr(new Date(), -2);
        wage.setSysDate(preMonth);
        wage.setIsDelete(0);
        List<SysWage> list = sysWageDao.getList(wage);
        //获取生成月份的工资集合，如果存在先删除在新增
        String thisMonth = getMonthStr(new Date(), -1);
        wage.setSysDate(thisMonth);
        List<SysWage> list1 = sysWageDao.getList(wage);
        if (!CollectionUtils.isEmpty(list1)) {
            for (SysWage sysWage : list1) {
                sysWageDao.delete(sysWage.getId());
            }
        }
        //生成上月工资
        for (SysWage sysWage : list) {
            sysWage.setSysDate(thisMonth);
            sysWage.setCreateTime(new Date());
            sysWage.setId(null);
        }
        sysWageDao.saveBatch(list);
    }


    /**
     * 获取时间的年月字符串。
     *
     * @param date     时间对象
     * @param addMonth 月份计算加减值
     * @return 年月字符串 yyyy-MM
     * @author licheng
     * @since V1.0.0
     */
    public String getMonthStr(Date date, int addMonth) {
        //格式化为年月
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar curr = Calendar.getInstance();
        curr.setTime(date);
        curr.add(Calendar.MONTH, addMonth);
        return sdf.format(curr.getTime());
    }


    public void add(SysWage wage) throws BaseException {
        SysWage parm = new SysWage();
        parm.setSysDate(wage.getSysDate());
        parm.setIsDelete(0);
        parm.setUserNum(wage.getUserNum());
        List<SysWage> wages = sysWageDao.getList(parm);
        if (!CollectionUtils.isEmpty(wages)) {
            throw new BaseException("添加失败!该人员在该月下已存在工资明细!");
        }
        wage.setCreateTime(new Date());
        sysWageDao.save(wage);
    }

    public SysWage getById(Integer id) {
        return sysWageDao.getById(id);
    }

    public void doBatchEdit(String sysDate, String detail, Integer deptId, String money) throws NoSuchFieldException {
        //根据部门和时间查询工资信息
        SysWage wage = new SysWage();
        if(new Integer(-1).equals(deptId)){
            wage.setDeptId(null);
        }else {
            wage.setDeptId(deptId);
        }

        wage.setSysDate(sysDate);
        List<SysWage> wages = sysWageDao.getList(wage);
        if (!CollectionUtils.isEmpty(wages)) {
            for (SysWage sysWage : wages) {
                ClassUtil.setValue(sysWage, sysWage.getClass(), detail, SysWage.class.getDeclaredField(detail).getType(), money);
                if(Double.parseDouble(sysWage.getUserSalaryscale())>500){
                    sysWage.setUserSalaryscale("500.00");
                }
                initSysWage(sysWage);
                sysWageDao.update(sysWage);
            }
        }
    }

    /**
     * 同项设置
     * @param sysDate
     * @param detail
     * @param deptId
     * @param money
     * @throws NoSuchFieldException
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public void doSameEdit(String sysDate, String detail, Integer deptId, String money,Integer type) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        //根据部门和时间查询工资信息
        SysWage wage = new SysWage();
        if(new Integer(-1).equals(deptId)){
            wage.setDeptId(null);
        }else {
            wage.setDeptId(deptId);
        }

        wage.setSysDate(sysDate);
        List<SysWage> wages = sysWageDao.getList(wage);
        if (!CollectionUtils.isEmpty(wages)) {
            for (SysWage sysWage : wages) {
                ClassUtil.setValueForAdd(sysWage, sysWage.getClass(), detail, SysWage.class.getDeclaredField(detail).getType(), money,type);
                if(Double.parseDouble(sysWage.getUserSalaryscale())>500){
                    sysWage.setUserSalaryscale("500.00");
                }
                initSysWage(sysWage);
                sysWageDao.update(sysWage);
            }
        }
    }


    /**
     * 计算工资
     *
     * @param wage
     */
    public void initSysWage(SysWage wage) {
        //计算应发工资
        BigDecimal userPayablewage = new BigDecimal(0.00);
        userPayablewage = new BigDecimal(wage.getUesrBasicwage())
                .add(new BigDecimal(wage.getUserSalaryscale()))
                .add(new BigDecimal(wage.getUserMiles()))
                .add(new BigDecimal(wage.getUserMisuse()))
                .add(new BigDecimal(wage.getUserOvertimepay()))
                .add(new BigDecimal(wage.getUserOrther1()));
        wage.setUserPayablewage(userPayablewage.toString());
        //计算所得税
        BigDecimal userIncometax = userPayablewage.subtract(new BigDecimal(wage.getUserSocialsecurity()))
                .subtract(new BigDecimal(wage.getUserAccumulation()))
                .subtract(new BigDecimal(wage.getUserAbsenteeism()))
                .add(new BigDecimal(wage.getCarPay()))
                .subtract(new BigDecimal(wage.getDeductions()));
        if (userIncometax.compareTo(new BigDecimal(5000)) > 0) {
            BigDecimal dif = userIncometax.subtract(new BigDecimal(5000));
            if (dif.compareTo(new BigDecimal(0)) > 0 && dif.compareTo(new BigDecimal(3000)) <= 0) {
                wage.setUserIncometax(dif.multiply(new BigDecimal(0.03)).toString());
            } else if (dif.compareTo(new BigDecimal(3000)) > 0 && dif.compareTo(new BigDecimal(12000)) <= 0) {
                wage.setUserIncometax(dif.multiply(new BigDecimal(0.1)).subtract(new BigDecimal(210)).toString());
            } else if (dif.compareTo(new BigDecimal(12000)) > 0 && dif.compareTo(new BigDecimal(25000)) <= 0) {
                wage.setUserIncometax(dif.multiply(new BigDecimal(0.2)).subtract(new BigDecimal(1410)).toString());
            } else if (dif.compareTo(new BigDecimal(25000)) > 0 && dif.compareTo(new BigDecimal(35000)) <= 0) {
                wage.setUserIncometax(dif.multiply(new BigDecimal(0.25)).subtract(new BigDecimal(2660)).toString());
            } else if (dif.compareTo(new BigDecimal(35000)) > 0 && dif.compareTo(new BigDecimal(55000)) <= 0) {
                wage.setUserIncometax(dif.multiply(new BigDecimal(0.3)).subtract(new BigDecimal(4410)).toString());
            } else if (dif.compareTo(new BigDecimal(55000)) > 0 && dif.compareTo(new BigDecimal(80000)) <= 0) {
                wage.setUserIncometax(dif.multiply(new BigDecimal(0.35)).subtract(new BigDecimal(7160)).toString());
            } else if (dif.compareTo(new BigDecimal(80000)) > 0) {
                wage.setUserIncometax(dif.multiply(new BigDecimal(0.45)).subtract(new BigDecimal(15160)).toString());
            }

        } else {
            wage.setUserIncometax("0.00");
        }
        //计算实发工资
        BigDecimal userNetpayroll = new BigDecimal(wage.getUserPayablewage())
                .subtract(new BigDecimal(wage.getUserSocialsecurity()))
                .subtract(new BigDecimal(wage.getUserAccumulation()))
                .subtract(new BigDecimal(wage.getUserAbsenteeism()))
                .subtract(new BigDecimal(wage.getUserIncometax()))
                .subtract(new BigDecimal(wage.getUserOther2()));
        wage.setUserNetpayroll(userNetpayroll.toString());

    }
    public void initWage(SysWage wage) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        Field[] fields=wage.getClass().getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            if(field.getType().getName().equals("java.lang.String") && !name.equals("userNum")){
                name = name.substring(0, 1).toUpperCase() + name.substring(1);
                Method m = wage.getClass().getMethod("get" + name);
                String val = (String) m.invoke(wage);
                if(val!=null){
                    if(val.length()==0){
                        Method m2 = wage.getClass().getMethod("set" + name,
                                field.getType());
                        m2.invoke(wage, "0.00");
                    }

                }
            }else {
                continue;
            }

        }
    }

    public List<SysWage> getSumList(SysWage sysWage){
        if(StringUtils.isEmpty(sysWage.getSysDate())){
            sysWage.setSysDate(getMonthStr(new Date(),-1));

        }
        List<SysWage> sysWages=sysWageDao.getSumList(sysWage);
        SysWage totalWage=new SysWage();
        initTotalWages(totalWage,sysWages);
        totalWage.setDeptName("总计");
        sysWages.add(totalWage);
        return sysWages;
    }
    public int getSumCount(SysWage sysWage){
        return sysWageDao.getListCount(sysWage);
    }
    public void initTotalWages(SysWage totalWage,List<SysWage> sysWages){
        totalWage.setUesrBasicwage("0");
        totalWage.setUserSalaryscale("0");
        totalWage.setUserMiles("0");
        totalWage.setUserMisuse("0");
        totalWage.setUserOvertimepay("0");
        totalWage.setUserOrther1("0");
        totalWage.setUserPayablewage("0");
        totalWage.setUserSocialsecurity("0");
        totalWage.setUserAccumulation("0");
        totalWage.setUserAbsenteeism("0");
        totalWage.setUserIncometax("0");
        totalWage.setUserOther2("0");
        totalWage.setUserNetpayroll("0");
        for (SysWage wage : sysWages) {
            totalWage.setUesrBasicwage(new BigDecimal(totalWage.getUesrBasicwage()).add(new BigDecimal(wage.getUesrBasicwage())).toString());
            totalWage.setUserSalaryscale(new BigDecimal(totalWage.getUserSalaryscale()).add(new BigDecimal(wage.getUserSalaryscale())).toString());
            totalWage.setUserMiles(new BigDecimal(totalWage.getUserMiles()).add(new BigDecimal(wage.getUserMiles())).toString());
            totalWage.setUserMisuse(new BigDecimal(totalWage.getUserMisuse()).add(new BigDecimal(wage.getUserMisuse())).toString());
            totalWage.setUserOvertimepay(new BigDecimal(totalWage.getUserOvertimepay()).add(new BigDecimal(wage.getUserOvertimepay())).toString());
            totalWage.setUserOrther1(new BigDecimal(totalWage.getUserOrther1()).add(new BigDecimal(wage.getUserOrther1())).toString());
            totalWage.setUserPayablewage(new BigDecimal(totalWage.getUserPayablewage()).add(new BigDecimal(wage.getUserPayablewage())).toString());
            totalWage.setUserSocialsecurity(new BigDecimal(totalWage.getUserSocialsecurity()).add(new BigDecimal(wage.getUserSocialsecurity())).toString());
            totalWage.setUserAccumulation(new BigDecimal(totalWage.getUserAccumulation()).add(new BigDecimal(wage.getUserAccumulation())).toString());
            totalWage.setUserAbsenteeism(new BigDecimal(totalWage.getUserAbsenteeism()).add(new BigDecimal(wage.getUserAbsenteeism())).toString());
            totalWage.setUserIncometax(new BigDecimal(totalWage.getUserIncometax()).add(new BigDecimal(wage.getUserIncometax())).toString());
            totalWage.setUserOther2(new BigDecimal(totalWage.getUserOther2()).add(new BigDecimal( wage.getUserOther2())).toString());
            totalWage.setUserNetpayroll(new BigDecimal(totalWage.getUserNetpayroll()).add(new BigDecimal(wage.getUserNetpayroll())).toString());
        }

    }
    public List<SysWage> getList(SysWage wage){
        List<SysWage> sysWages=sysWageDao.getList(wage);
        SysWage totalWage=new SysWage();
        initTotalWages(totalWage,sysWages);
        totalWage.setUserName("总计");
        sysWages.add(totalWage);
        return sysWages;
    }
}
